food demand forecast

Author

Karani Keith

Introduction

A meal delivery company which operates in multiple cities. It have various fulfillment centers in these cities for dispatching meal orders to their customers. My goal is to help these centers with demand forecasting for upcoming weeks so that these centers will plan the stock of raw materials accordingly.

Objective

The replenishment of majority of raw materials is done on weekly basis and since the raw material is perishable, the procurement planning is of utmost importance. To predict the demand for the next 10 weeks (Weeks: 146-155) for the center-meal combinations in the test set.

Secondly, staffing of the centers is also one area wherein accurate demand forecasts are really helpful.

load the libraries to use

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.4.4     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.0
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tsibble)

Attaching package: 'tsibble'

The following object is masked from 'package:lubridate':

    interval

The following objects are masked from 'package:base':

    intersect, setdiff, union

load the data sets to use

fulfilment_center_info <- read_csv("data/fulfilment_center_info.xls")
Rows: 77 Columns: 5
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (1): center_type
dbl (4): center_id, city_code, region_code, op_area

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(fulfilment_center_info)


meal_info <- read_csv("data/meal_info.xls")
Rows: 51 Columns: 3
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (2): category, cuisine
dbl (1): meal_id

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(meal_info)


test <- read_csv("data/test.csv")
Rows: 32573 Columns: 8
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
dbl (8): id, week, center_id, meal_id, checkout_price, base_price, emailer_f...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(test)



train <- read_csv("data/train.csv")
Rows: 456548 Columns: 9
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
dbl (9): id, week, center_id, meal_id, checkout_price, base_price, emailer_f...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(train)

Check for duplicates and NA values

train %>% 
  group_by(week, center_id, meal_id) %>% 
  summarise(count=n()) %>% 
  filter(count>1) #no dup
`summarise()` has grouped output by 'week', 'center_id'. You can override using
the `.groups` argument.
# A tibble: 0 × 4
# Groups:   week, center_id [0]
# ℹ 4 variables: week <dbl>, center_id <dbl>, meal_id <dbl>, count <int>
train %>% 
  group_by(week, center_id) %>% 
  summarize(count=n()) %>% 
  arrange(desc(count))
`summarise()` has grouped output by 'week'. You can override using the
`.groups` argument.
# A tibble: 11,140 × 3
# Groups:   week [145]
    week center_id count
   <dbl>     <dbl> <int>
 1   112        13    51
 2   113        10    51
 3   113        52    51
 4   114        10    51
 5   114        13    51
 6   114        52    51
 7   115        10    51
 8   115        13    51
 9   115        20    51
10   115        43    51
# ℹ 11,130 more rows
train %>% 
  group_by(center_id, meal_id) %>% 
  summarize(count=n()) %>% 
  arrange(desc(count)) # a lot of intermittent demand
`summarise()` has grouped output by 'center_id'. You can override using the
`.groups` argument.
# A tibble: 3,597 × 3
# Groups:   center_id [77]
   center_id meal_id count
       <dbl>   <dbl> <int>
 1        10    1062   145
 2        10    1109   145
 3        10    1198   145
 4        10    1230   145
 5        10    1248   145
 6        10    1311   145
 7        10    1445   145
 8        10    1543   145
 9        10    1727   145
10        10    1754   145
# ℹ 3,587 more rows
meal_info %>% 
  summarise(count=n()) #total 51 meals, some centers dont offer every meal
# A tibble: 1 × 1
  count
  <int>
1    51
colSums(is.na(train)) #no NA
                   id                  week             center_id 
                    0                     0                     0 
              meal_id        checkout_price            base_price 
                    0                     0                     0 
emailer_for_promotion     homepage_featured            num_orders 
                    0                     0                     0 
train %>% 
  arrange(num_orders) #no 0 order, 
# A tibble: 456,548 × 9
        id  week center_id meal_id checkout_price base_price
     <dbl> <dbl>     <dbl>   <dbl>          <dbl>      <dbl>
 1 1336534     1        55    1445           629.       628.
 2 1012819     1        55    2867           629.       627.
 3 1325272     1        55    2704           244.       282.
 4 1412058     1        55    2304           484.       484.
 5 1435407     1        11    1216           457.       457.
 6 1011853     1        83    1902           484.       485.
 7 1086441     1        32    2139           455.       455.
 8 1461939     1        13    1216           455.       457.
 9 1403661     1        93    2492           446.       446.
10 1170767     1       186    2139           455.       455.
# ℹ 456,538 more rows
# ℹ 3 more variables: emailer_for_promotion <dbl>, homepage_featured <dbl>,
#   num_orders <dbl>

group analysis

full1 <- left_join(train, fulfilment_center_info, by="center_id")
names(full1)
 [1] "id"                    "week"                  "center_id"            
 [4] "meal_id"               "checkout_price"        "base_price"           
 [7] "emailer_for_promotion" "homepage_featured"     "num_orders"           
[10] "city_code"             "region_code"           "center_type"          
[13] "op_area"              
full_df <- left_join(full1, meal_info, by="meal_id")

names(full_df)
 [1] "id"                    "week"                  "center_id"            
 [4] "meal_id"               "checkout_price"        "base_price"           
 [7] "emailer_for_promotion" "homepage_featured"     "num_orders"           
[10] "city_code"             "region_code"           "center_type"          
[13] "op_area"               "category"              "cuisine"              
ts <- full_df %>% 
  mutate(cm_id=str_c(center_id, meal_id)) %>% 
  as_tsibble(index =week, key=cm_id )

names(ts)
 [1] "id"                    "week"                  "center_id"            
 [4] "meal_id"               "checkout_price"        "base_price"           
 [7] "emailer_for_promotion" "homepage_featured"     "num_orders"           
[10] "city_code"             "region_code"           "center_type"          
[13] "op_area"               "category"              "cuisine"              
[16] "cm_id"                
View(ts)

sales over time from the fulfillment centers

library(crosstalk)
library(plotly)

Attaching package: 'plotly'
The following object is masked from 'package:ggplot2':

    last_plot
The following object is masked from 'package:stats':

    filter
The following object is masked from 'package:graphics':

    layout
gg <- ts %>% 
  ggplot(aes(week, num_orders, col=cm_id, group=cm_id))+
  geom_line(show.legend = FALSE)+
  labs(title = "Individual ts")

shared_ts <- SharedData$new(ts)

filter <- bscols(
  filter_select("ids", "Sales over time: Select a time series ID (remove with backspace key, navigate with arrow keys):", shared_ts, ~cm_id, multiple = TRUE),
  ggplotly(gg, dynamicTicks = TRUE),
  widths = c(12, 12)
)
Warning in bscols(filter_select("ids", "Sales over time: Select a time series
ID (remove with backspace key, navigate with arrow keys):", : Sum of bscol
width units is greater than 12
bscols(filter)
findings
  1. Most meals weekly orders counts are below 2500 indicating noises.
  2. cm_id 43_2290 starts with an outlier
  3. some meals have zero in the ts

All aggregated sales

library(ggthemes)
?index_by

foo <- ts %>% 
  index_by(week) %>% 
  summarise(sum_orders=sum(num_orders)) 

gg <- foo %>% 
  ggplot(aes(week, sum_orders)) +
  geom_line(col="blue") +
  geom_vline(xintercept = c(53, 105), alpha=0.3, linetype=2) +
  labs(title = "All intergrated sales") +
  theme_tufte()
ggplotly(gg, dynamicTicks = TRUE)
Observations
  1. Overall, the demand can be termed as stable with a little drop from week 109 suggesting the business is in its mature period.
  2. Demand is generally stable with two high spikes i.e week 5 and week 48 and a dip in week 62.
  3. I have added the grey dash lines every 52weeks since there might be some seasonality but not clear.

Sales per region / city

foo <- ts %>% 
  index_by(week) %>% 
  group_by(region_code) %>% 
  summarise(sum_orders=sum(num_orders))

pl <- foo %>% 
  ggplot(aes(week, sum_orders)) +
  geom_line(aes(col=region_code), show.legend = FALSE) +
  geom_vline(xintercept = c(53, 105), linetype=2, alpha=0.3) +
  theme_tufte() +
  labs(title = "sales by region")
ggplotly(pl, dynamicTicks = TRUE)
ts[,-2] %>% 
  group_by(region_code) %>% 
  summarise(area=round(mean(op_area), 1)) %>% 
  ggplot(aes(as.factor(region_code), area))+
  geom_col(fill="blue", show.legend = FALSE)+
  labs(title="region and op areas")+
  geom_text(aes(label=area), nudge_y = 0.2)

foo <- ts %>% 
  index_by(week) %>% 
  group_by(region_code, center_id) %>% 
  summarise(sum_orders=sum(sum(num_orders)))

p2 <- foo %>% 
  filter(!is.na(region_code)) %>% 
  ggplot(aes(week, sum_orders))+
  geom_line(aes(col=center_id, group=center_id), show.legend = FALSE)+
  geom_vline(xintercept = c(53, 105), linetype=2, alpha=0.3)+
  facet_wrap(~region_code, ncol = 2, scales = "free_y")+
  theme_tufte()+
  labs(title="sales per region")
ggplotly(p2, dynamicTicks = TRUE)
observations
  • Regions can be separated into 4 groups:

    G1-R56 has a clear higher demand than the rest regions with a weekly average orders at around 350k.

    G2-R34/77 ~88k,

    G3-85 ~60K and rest in G4

  • Despite the high demand differences between the regions, the pattern is similar across the group for instance a surge in week 5, a dip in week 62 which also matches the global pattern.

    This suggests that the demand surges apply to all regions and is not caused by a specific region.

  • The different operation areas are not reflected directly in the demand pattern

Regions in G4 group has only one distribution center each.

foo <- ts %>%
  index_by(week) %>% 
  group_by(city_code) %>% 
  summarise(sum_orders=sum(num_orders))

gg <- foo %>% 
  ggplot(aes(week, sum_orders))+
  geom_line(aes(col=city_code), show.legend = FALSE)+
  geom_vline(xintercept = c(53, 105), linetype=2, alpha=0.3)+
  theme_tufte()+
  labs(title="sales by city")
ggplotly(gg, dynamicTicks = TRUE)
Findings
  • City 590, 526, 638 has a higher demand than the rest

  • The general pattern is similar to the regional pattern

Sales per center type

library(tidyverse)
foo <- ts %>% 
  index_by(week) %>% 
  group_by(center_type) %>% 
  summarise(sum_orders=sum(num_orders))

gg <- foo %>% 
  ggplot(aes(week, sum_orders, group=center_type, col=center_type))+
  geom_line(show.legend = FALSE)+
  geom_vline(xintercept = c(53, 105), linetype=2, alpha=0.3)+
  theme_tufte()+
  labs(title="sales per center type")
ggplotly(gg, dynamicTicks = TRUE)
Findings
  • Type A>b>c

  • Patterns are similar across types

    Sales per category

foo <- ts %>% 
  index_by(week) %>% 
  group_by(category) %>% 
  summarise(sum_orders=sum(num_orders))

gg <- foo %>% 
  ggplot(aes(week, sum_orders, group=category, col=category))+
  geom_line(show.legend = FALSE)+
  geom_vline(xintercept = c(53, 105), linetype=2, alpha=0.3)+
  theme_tufte()+
  labs(title="sales per category")
ggplotly(gg, dynamicTicks = TRUE)

Sales per cuisine

foo <- ts %>% 
  index_by(week) %>% 
  group_by(cuisine) %>% 
  summarise(sum_orders=sum(num_orders))
gg <- foo %>% 
  ggplot(aes(week, sum_orders, group=cuisine, col=cuisine))+
  geom_line(show.legend = FALSE)+
  geom_vline(xintercept = c(53, 105), linetype=2, alpha=0.3)+
  theme_tufte()+
  labs(title="sales per cusine")
ggplotly(gg, dynamicTicks = TRUE)

Cuisine per region

foo <- ts %>% 
  index_by(week) %>% 
  group_by(region_code, cuisine) %>% 
  summarise(sum_orders=sum(num_orders))
gg <- foo %>% 
  filter(!is.na(region_code)) %>% 
  ggplot(aes(week, sum_orders, group=cuisine, col=cuisine))+
  geom_line(show.legend = FALSE)+
  geom_vline(xintercept = c(53, 105), linetype=2, alpha=0.3)+
  theme_tufte()+
  labs(title="cuisine per region")+
  facet_grid(region_code~cuisine, scales = "free_y")
ggplotly(gg, dynamicTicks = TRUE)
Observations
  1. Region 93 has a two spike of Thai food in week 46/98(+52) showing a clear seasonality. It’s the only region that Thai food surpluses Indian & Italian food suggesting there might be more Thai people dwelling in that region.
  2. Overall we can see Italian > Indian > Thai = continental.
foo <- ts %>% 
  index_by(week) %>% 
  group_by(region_code, category) %>% 
  summarise(sum_orders=sum(num_orders))

gg <- foo %>% 
  filter(!is.na(region_code)) %>% 
  ggplot(aes(week, sum_orders, group=category, col=category))+
  geom_line()+
  theme_tufte()+
  labs(title="category per region")+
  facet_grid(region_code~category)
ggplotly(gg, dynamicTicks = TRUE)
Findings
  1. Rice Beverage/bowls/ sandwich/ Pizza / Salad are driving the sales in all regions.
  2. Seafood / starters / snacks comes in 2nd place.
  3. Some regions don’t offer extra soup.
  4. Some regions have began the business in extra category
  5. Its worth noting that the demand of beverages are quite different across the regions.

Explanatory variables

a) variable correlations
library(data.table)

Attaching package: 'data.table'
The following object is masked from 'package:tsibble':

    key
The following objects are masked from 'package:lubridate':

    hour, isoweek, mday, minute, month, quarter, second, wday, week,
    yday, year
The following objects are masked from 'package:dplyr':

    between, first, last
The following object is masked from 'package:purrr':

    transpose
# Calculate the correlation matrix
correlation_matrix <- cor(train)
cor_matrix <- melt(correlation_matrix)
Warning in melt(correlation_matrix): The melt generic in data.table has been
passed a matrix and will attempt to redirect to the relevant reshape2 method;
please note that reshape2 is deprecated, and this redirection is now deprecated
as well. To continue using melt methods from reshape2 while both libraries are
attached, e.g. melt.list, you can prepend the namespace like
reshape2::melt(correlation_matrix). In the next version, this warning will
become an error.
cor_matrix$value <- round(cor_matrix$value,4)

# Plot the correlation matrix as a heatmap
plt <- ggplot(data =cor_matrix, aes(Var2, Var1, fill = value)) +
  geom_tile(show.legend = FALSE) +
  geom_text(aes(label=value), size=2)+
  scale_fill_gradient(low = "white", high = "blue") +
  labs(title = "Correlation Coefficient", x = "", y = "") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

plt

b) homepage promotions
library(ggthemes)
library(plotly)


h_pro <- ts %>% 
  filter(!homepage_featured==0) %>% 
  as.tibble() %>% 
  group_by(cm_id) %>% 
  summarise(sum_orders=sum(num_orders)) %>% 
  select(-2)
Warning: `as.tibble()` was deprecated in tibble 2.0.0.
ℹ Please use `as_tibble()` instead.
ℹ The signature and semantics have changed, see `?as_tibble`.
sample_id <- function(df, vector, region_code, cuisine){
  df %>% 
    filter(cm_id %in% vector, region_code==region_code, cuisine==cuisine) %>% 
    head(1) %>% 
    pull(cm_id)
}

a <- ts %>% 
    filter(cm_id %in% h_pro$cm_id, region_code==56, cuisine=="Italian") %>% 
    head(1) %>% 
    pull(cm_id)
b <- ts %>% 
    filter(cm_id %in% h_pro$cm_id, region_code==34, cuisine=="Continental") %>% 
    head(1) %>% 
    pull(cm_id)
c <- ts %>% 
    filter(cm_id %in% h_pro$cm_id, region_code==85, cuisine=="Indian") %>% 
    head(1) %>% 
    pull(cm_id)
d <- ts %>% 
    filter(cm_id %in% h_pro$cm_id, region_code==93, cuisine=="Thai") %>% 
    head(1) %>% 
    pull(cm_id)
sample <- tibble(sample=c(a,b,c,d))
p1 <- ts %>% 
  filter(cm_id %in% sample$sample, !is.na(cuisine)) %>% 
  mutate(has_hpro=if_else(homepage_featured==1, num_orders, NA_real_)) %>% 
  ggplot(aes(week, num_orders, group=cm_id))+
  geom_line(aes(col=cuisine), na.rm=TRUE)+
  geom_point(aes(week, has_hpro), na.rm = TRUE)+
  facet_wrap(~cm_id, ncol=1, scales = "free_y")+
  labs(title="Sales for 3 random meals with homepage promotion", 
       col="Cuisine")+
  theme_tufte()
ggplotly(p1, dynamicTicks = TRUE)
Findings
  1. For Italian and Indian cuisine, the homepage promotions bring a peak in the week, with demand dropping in the following week
  2. For continental cuisine, we see the promotion last the first 120 weeks, bringing some ups and downs in demand, suggesting the company is promoting the sales of this category. we also see the demand dropped after the promotion.
  3. For Thai food, promotions generally increased the demand, which, however, dropped immediately afterwards
c) emailer for promotion
e_pro <- ts %>% 
  filter(!emailer_for_promotion==0) %>% 
  as.tibble() %>% 
  mutate(id=str_c(cm_id, region_code, sep="_")) %>% 
  group_by(id) %>% 
  summarise(sum_orders=sum(num_orders)) %>% 
  select(-2)

foo <- ts %>% 
  mutate(id=str_c(cm_id, region_code, sep="_"))
a <- foo %>% 
    filter(id %in% e_pro$id, region_code==56, cuisine=="Italian") %>% 
    head(1) %>% 
    pull(id)
b <- foo %>% 
    filter(id %in% e_pro$id, region_code==34, cuisine=="Continental") %>% 
    head(1) %>% 
    pull(id)
c <- foo %>% 
    filter(id %in% e_pro$id, region_code==85, cuisine=="Indian") %>% 
    head(1) %>% 
    pull(id)
d <- foo %>% 
    filter(id %in% e_pro$id, region_code==93, cuisine=="Thai") %>% 
    head(1) %>% 
    pull(id)
sample <- tibble(sample=c(a,b,c,d))

p1 <- foo %>% 
  filter(id %in% sample$sample, !is.na(cuisine)) %>% 
  mutate(has_epro=if_else(emailer_for_promotion==1, num_orders, NA_real_)) %>% 
  ggplot(aes(week, num_orders, group=id))+
  geom_line(aes(col=cuisine), na.rm=TRUE)+
  geom_point(aes(week, has_epro), na.rm = TRUE)+
  facet_wrap(~id, ncol=1, scales = "free_y")+
  labs(title="Sales for 3 random meals with email promotion", 
       col="Cuisine")+
  theme_tufte()
ggplotly(p1, dynamicTicks = TRUE)
observations
  1. For Indian/Italian cuisines, we see similar patterns as the homepage promotion, demand reaching the top in the week and reducing in following week.
  2. For Continental cuisine, we see a lagged 3 to lagged 4 effect.
  3. For Thai food, promotions generally increased the demand, which, however, dropped immediately afterwards.
d) price effect
library(ggridges)

foo <- ts %>% 
  mutate(year=if_else(week<=52, 1, if_else(week<=104, 2, 3)))

gg <- foo %>% 
  filter(!is.na(region_code), num_orders!=0) %>% 
  ggplot(aes(checkout_price, as.factor(year)))+
  geom_density_ridges(bw=0.5, alpha=0.5)+
  scale_x_continuous(trans = "log10", breaks = c(100, 300, 500, 800, 1000))+
  coord_cartesian(xlim = c(90, 1000))+
  facet_wrap(~cuisine)+
  labs(title="Price change with time", x="Price", y="Year")+
  theme_hc()
Warning in geom_density_ridges(bw = 0.5, alpha = 0.5): Ignoring unknown
parameters: `bw`
gg
Picking joint bandwidth of 0.014
Picking joint bandwidth of 0.0193
Picking joint bandwidth of 0.0147
Picking joint bandwidth of 0.0168

observations
  1. The price is clearly increasing with time for all cuisines(the wave pattern moving towards the right side).
  2. The continental and Indian food are priced higher than Italian and Thai food
  3. Continental and Thai food share the similar change pattern that the last peaks become bi modal overtime. For continental food, the peak at 700 is gaining importance until it reaches the peak at 600. Similarly, for Thai food, 400 group is becoming as important as the 300 group.

EDA observations

  • There are 8 regions, 51 citys and 77 fulfillment centers

  • ome region has only one center(23, 35, 71, 93), the rest has multiple.

  • The demand pattern is pretty similar in regards to Italian/Indian cuisine but quite different about Thai.

  • The aggregated demand is stable with a bit decreasing trend while the overall price is slightly increasing. It suggests the price might correlate to the demand in a negative way.

  • The homepage/email promotions affect different materials in a different way. The promotion frequencies are also different.

  • Region 35/85/93 doesn’t offer soup/extras. Region 71 doesn’t offer soup but just started the extra business.

  • Most regions prefers Italian>Indian>Continental>Thai while region 93 shows some unique preference wards Thai whose demand is highest in 4 regions.

  • There are some unusual surges and drops in demands

  • Beverage/rice bowls/sandwiches are top 3 categories

Modeling

Given the above factors, the following models are considered

  1. Dynamic regression model(DR) to correlate price change and promotion

  2. Decomposition model(STL) to take care of the unusual dips(w62) and surges.

  3. NAIVE model as the benchmark model.

total aggregated Model building
  1. weekly data: STL+non_seasonal approach to season adjust
  2. Dynamic harmonic regression cant be used
library(fable)
Loading required package: fabletools
library(feasts)
library(urca)
library(patchwork)
library(gridExtra)

Attaching package: 'gridExtra'
The following object is masked from 'package:dplyr':

    combine
foo <- ts
full_ts <- foo %>% 
  as.tibble() %>% 
  group_by(cm_id) %>% 
  summarise(count=n()) %>% 
  filter(count==145) %>% 
  select(1)

part_ts <- foo %>% 
  as.tibble() %>% 
  group_by(cm_id) %>% 
  summarise(count=n()) %>% 
  filter(count!=145) %>% 
  select(1)

foo1 <- foo %>% 
  filter(cm_id %in% full_ts$cm_id)
fit <- foo1 %>% 
  model(stl=decomposition_model(STL(num_orders, robust=TRUE),
                                ETS(season_adjust~season("N"))),
        arima=ARIMA(log(num_orders)))

p1 <- fit %>% 
  select(stl) %>% 
  augment() %>% 
  ggplot(aes(week, num_orders))+
  geom_line()+
  geom_line(aes(y=.fitted), col="blue")

p2 <- fit %>% 
  select(arima) %>% 
  augment() %>% 
  ggplot(aes(week, num_orders))+
  geom_line()+
  geom_line(aes(y=.fitted), col="red")

p1

any(is.na(p1))
[1] FALSE
head(p1)
$data
# A tsibble: 180,815 x 7 [1]
# Key:       cm_id, .model [1,247]
   cm_id  .model  week num_orders .fitted  .resid  .innov
   <chr>  <chr>  <dbl>      <dbl>   <dbl>   <dbl>   <dbl>
 1 101062 stl        1        865    962.  -96.7   -96.7 
 2 101062 stl        2        782    935. -153.   -153.  
 3 101062 stl        3        851    892.  -41.4   -41.4 
 4 101062 stl        4       1202    881.  321.    321.  
 5 101062 stl        5        958    970.  -12.1   -12.1 
 6 101062 stl        6       1094    967.  127.    127.  
 7 101062 stl        7       1513   1002.  511.    511.  
 8 101062 stl        8       1149   1144.    4.91    4.91
 9 101062 stl        9       1282   1145.  137.    137.  
10 101062 stl       10       1473   1183.  290.    290.  
# ℹ 180,805 more rows

$layers
$layers[[1]]
geom_line: na.rm = FALSE, orientation = NA
stat_identity: na.rm = FALSE
position_identity 

$layers[[2]]
mapping: y = ~.fitted 
geom_line: na.rm = FALSE, orientation = NA
stat_identity: na.rm = FALSE
position_identity 


$scales
<ggproto object: Class ScalesList, gg>
    add: function
    clone: function
    find: function
    get_scales: function
    has_scale: function
    input: function
    n: function
    non_position_scales: function
    scales: list
    super:  <ggproto object: Class ScalesList, gg>

$mapping
Aesthetic mapping: 
* `x` -> `week`
* `y` -> `num_orders`

$theme
list()

$coordinates
<ggproto object: Class CoordCartesian, Coord, gg>
    aspect: function
    backtransform_range: function
    clip: on
    default: TRUE
    distance: function
    expand: TRUE
    is_free: function
    is_linear: function
    labels: function
    limits: list
    modify_scales: function
    range: function
    render_axis_h: function
    render_axis_v: function
    render_bg: function
    render_fg: function
    setup_data: function
    setup_layout: function
    setup_panel_guides: function
    setup_panel_params: function
    setup_params: function
    train_panel_guides: function
    transform: function
    super:  <ggproto object: Class CoordCartesian, Coord, gg>
p2

any(is.na(p2))
[1] FALSE
head(p2)
$data
# A tsibble: 180,815 x 7 [1]
# Key:       cm_id, .model [1,247]
   cm_id  .model  week num_orders .fitted  .resid   .innov
   <chr>  <chr>  <dbl>      <dbl>   <dbl>   <dbl>    <dbl>
 1 101062 arima      1        865    907.  -41.8  -0.0472 
 2 101062 arima      2        782    894. -112.   -0.134  
 3 101062 arima      3        851    867.  -15.7  -0.0182 
 4 101062 arima      4       1202    876.  326.    0.316  
 5 101062 arima      5        958    966.   -8.02 -0.00833
 6 101062 arima      6       1094    945.  149.    0.146  
 7 101062 arima      7       1513    971.  542.    0.443  
 8 101062 arima      8       1149   1072.   77.4   0.0697 
 9 101062 arima      9       1282   1035.  247.    0.214  
10 101062 arima     10       1473   1052.  421.    0.337  
# ℹ 180,805 more rows

$layers
$layers[[1]]
geom_line: na.rm = FALSE, orientation = NA
stat_identity: na.rm = FALSE
position_identity 

$layers[[2]]
mapping: y = ~.fitted 
geom_line: na.rm = FALSE, orientation = NA
stat_identity: na.rm = FALSE
position_identity 


$scales
<ggproto object: Class ScalesList, gg>
    add: function
    clone: function
    find: function
    get_scales: function
    has_scale: function
    input: function
    n: function
    non_position_scales: function
    scales: list
    super:  <ggproto object: Class ScalesList, gg>

$mapping
Aesthetic mapping: 
* `x` -> `week`
* `y` -> `num_orders`

$theme
list()

$coordinates
<ggproto object: Class CoordCartesian, Coord, gg>
    aspect: function
    backtransform_range: function
    clip: on
    default: TRUE
    distance: function
    expand: TRUE
    is_free: function
    is_linear: function
    labels: function
    limits: list
    modify_scales: function
    range: function
    render_axis_h: function
    render_axis_v: function
    render_bg: function
    render_fg: function
    setup_data: function
    setup_layout: function
    setup_panel_guides: function
    setup_panel_params: function
    setup_params: function
    train_panel_guides: function
    transform: function
    super:  <ggproto object: Class CoordCartesian, Coord, gg>
p1/p2

Individual forecast plot
library(gridExtra)

ts <- ts %>% 
  fill_gaps(emailer_for_promotion=0, homepage_featured=0, num_orders=0,
            .full=TRUE) %>% 
  group_by(cm_id) %>%
  fill(c(3:6, 10:15), .direction = "downup")

# data frame created for model fitiing
full_ts <- foo %>% 
  as.tibble() %>% 
  group_by(cm_id) %>% 
  summarise(count=n()) %>% 
  filter(count==145) %>% 
  select(1)
part_ts <- foo %>% 
  as.tibble() %>% 
  group_by(cm_id) %>% 
  summarise(count=n()) %>% 
  filter(count!=145, count!=1) %>% 
  select(1)

single_ts <- foo %>% 
  as.tibble() %>% 
  group_by(cm_id) %>% 
  summarise(count=n()) %>% 
  filter(count==1) %>% 
  select(1)

# fit the model using ARIMA
fit <- ts %>% 
  filter(cm_id %in% full_ts$cm_id) %>% 
  model(dr=ARIMA(num_orders~checkout_price))

fit2 <- ts %>% 
  filter(cm_id %in% part_ts$cm_id) %>% 
  model(itmt=CROSTON(num_orders))
# 
full3 <- left_join(test, fulfilment_center_info, by="center_id")
full_df3 <- left_join(full3, meal_info, by="meal_id")

test <- full_df3 %>% 
  mutate(cm_id=str_c(center_id, meal_id)) %>% 
  as_tsibble(index =week, key=cm_id ) %>% 
  fill_gaps(emailer_for_promotion=0, homepage_featured=0, .full=TRUE) %>% 
  group_by(cm_id) %>%
  fill(c(3:6, 9:14), .direction = "downup")
test_full <- test %>% 
  filter(cm_id %in% full_ts$cm_id)
test_part <- test %>% 
  filter(cm_id %in% part_ts$cm_id)

# forecasing using the fitted models
fc <- forecast(fit, test_full)
fc2 <- forecast(fit2, test_part)
fc <- bind_rows(fc, fc2)

#visualiaze the focast
p1 <- ts %>% 
  filter(cm_id=="101062") %>% 
  ggplot(aes(week, num_orders))+
  geom_line()+
  geom_line(data=fc[fc$cm_id=="101062", ], aes(week, .mean), col="blue")+
  labs(title="meal 1062 by center", size=1)+
  theme_classic()
Warning: The output of `fortify(<fable>)` has changed to better suit usage with the ggdist package.
If you're using it to extract intervals, consider using `hilo()` to compute intervals, and `unpack_hilo()` to obtain values.
meal_1062_590 <- ts %>% 
  filter(meal_id=="1062", city_code=="590") %>% 
  group_by(meal_id) %>% 
  summarise(sum_orders=sum(num_orders))

meal_fc_1062_590 <- fc %>% 
  as_tsibble() %>% 
  filter(meal_id=="1062", city_code=="590") %>% 
  summarise(sum_orders=sum(.mean))

p2 <- meal_1062_590 %>% 
  ggplot(aes(week, sum_orders)) +
  geom_line(size=0.5) +
  geom_line(data=meal_fc_1062_590, aes(week, sum_orders), col="red",size=1)+
  labs(title="meal 1062 by city")+
  theme_classic()
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
meal_1062_56 <- ts %>% 
  filter(meal_id=="1062", region_code=="56") %>% 
  group_by(meal_id) %>% 
  summarise(sum_orders=sum(num_orders))

meal_fc_1062_56 <- fc %>% 
  as_tsibble() %>% 
  filter(meal_id=="1062", region_code=="56") %>% 
  summarise(sum_orders=sum(.mean))

p3 <- meal_1062_56 %>% 
  ggplot(aes(week, sum_orders)) +
  geom_line(size=0.5) +
  geom_line(data=meal_fc_1062_56, aes(week, sum_orders), col="green",size=1)+
  labs(title="meal 1062 by region")+
  theme_classic()


p1

any(is.na(p1))
[1] FALSE
head(p1)
$data
# A tsibble: 145 x 17 [1]
# Key:       cm_id [1]
# Groups:    cm_id [1]
        id  week center_id meal_id checkout_price base_price
     <dbl> <dbl>     <dbl>   <dbl>          <dbl>      <dbl>
 1 1436842     1        10    1062           181.       181.
 2 1205013     2        10    1062           183.       182.
 3 1447751     3        10    1062           184.       182.
 4 1014968     4        10    1062           182.       183.
 5 1003563     5        10    1062           183.       181.
 6 1212869     6        10    1062           162.       183.
 7 1254112     7        10    1062           160.       183.
 8 1291467     8        10    1062           160.       182.
 9 1083552     9        10    1062           162.       182.
10 1325645    10        10    1062           161.       181.
# ℹ 135 more rows
# ℹ 11 more variables: emailer_for_promotion <dbl>, homepage_featured <dbl>,
#   num_orders <dbl>, city_code <dbl>, region_code <dbl>, center_type <chr>,
#   op_area <dbl>, category <chr>, cuisine <chr>, cm_id <chr>, .group <int>

$layers
$layers[[1]]
geom_line: na.rm = FALSE, orientation = NA
stat_identity: na.rm = FALSE
position_identity 

$layers[[2]]
mapping: x = ~week, y = ~.mean 
geom_line: na.rm = FALSE, orientation = NA
stat_identity: na.rm = FALSE
position_identity 


$scales
<ggproto object: Class ScalesList, gg>
    add: function
    clone: function
    find: function
    get_scales: function
    has_scale: function
    input: function
    n: function
    non_position_scales: function
    scales: list
    super:  <ggproto object: Class ScalesList, gg>

$mapping
Aesthetic mapping: 
* `x` -> `week`
* `y` -> `num_orders`

$theme
List of 97
 $ line                      :List of 6
  ..$ colour       : chr "black"
  ..$ linewidth    : num 0.5
  ..$ linetype     : num 1
  ..$ lineend      : chr "butt"
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ rect                      :List of 5
  ..$ fill         : chr "white"
  ..$ colour       : chr "black"
  ..$ linewidth    : num 0.5
  ..$ linetype     : num 1
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ text                      :List of 11
  ..$ family       : chr ""
  ..$ face         : chr "plain"
  ..$ colour       : chr "black"
  ..$ size         : num 11
  ..$ hjust        : num 0.5
  ..$ vjust        : num 0.5
  ..$ angle        : num 0
  ..$ lineheight   : num 0.9
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ title                     : NULL
 $ aspect.ratio              : NULL
 $ axis.title                : NULL
 $ axis.title.x              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 2.75points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.x.top          :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 2.75points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.x.bottom       : NULL
 $ axis.title.y              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : num 90
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 2.75points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.y.left         : NULL
 $ axis.title.y.right        :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : num -90
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.75points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text                 :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : chr "grey30"
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x               :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 2.2points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x.top           :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 2.2points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x.bottom        : NULL
 $ axis.text.y               :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 1
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 2.2points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.y.left          : NULL
 $ axis.text.y.right         :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.2points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.ticks                :List of 6
  ..$ colour       : chr "grey20"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ lineend      : NULL
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ axis.ticks.x              : NULL
 $ axis.ticks.x.top          : NULL
 $ axis.ticks.x.bottom       : NULL
 $ axis.ticks.y              : NULL
 $ axis.ticks.y.left         : NULL
 $ axis.ticks.y.right        : NULL
 $ axis.ticks.length         : 'simpleUnit' num 2.75points
  ..- attr(*, "unit")= int 8
 $ axis.ticks.length.x       : NULL
 $ axis.ticks.length.x.top   : NULL
 $ axis.ticks.length.x.bottom: NULL
 $ axis.ticks.length.y       : NULL
 $ axis.ticks.length.y.left  : NULL
 $ axis.ticks.length.y.right : NULL
 $ axis.line                 :List of 6
  ..$ colour       : chr "black"
  ..$ linewidth    : 'rel' num 1
  ..$ linetype     : NULL
  ..$ lineend      : NULL
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ axis.line.x               : NULL
 $ axis.line.x.top           : NULL
 $ axis.line.x.bottom        : NULL
 $ axis.line.y               : NULL
 $ axis.line.y.left          : NULL
 $ axis.line.y.right         : NULL
 $ legend.background         :List of 5
  ..$ fill         : NULL
  ..$ colour       : logi NA
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ legend.margin             : 'margin' num [1:4] 5.5points 5.5points 5.5points 5.5points
  ..- attr(*, "unit")= int 8
 $ legend.spacing            : 'simpleUnit' num 11points
  ..- attr(*, "unit")= int 8
 $ legend.spacing.x          : NULL
 $ legend.spacing.y          : NULL
 $ legend.key                : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ legend.key.size           : 'simpleUnit' num 1.2lines
  ..- attr(*, "unit")= int 3
 $ legend.key.height         : NULL
 $ legend.key.width          : NULL
 $ legend.text               :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ legend.text.align         : NULL
 $ legend.title              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ legend.title.align        : NULL
 $ legend.position           : chr "right"
 $ legend.direction          : NULL
 $ legend.justification      : chr "center"
 $ legend.box                : NULL
 $ legend.box.just           : NULL
 $ legend.box.margin         : 'margin' num [1:4] 0cm 0cm 0cm 0cm
  ..- attr(*, "unit")= int 1
 $ legend.box.background     : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ legend.box.spacing        : 'simpleUnit' num 11points
  ..- attr(*, "unit")= int 8
 $ panel.background          :List of 5
  ..$ fill         : chr "white"
  ..$ colour       : logi NA
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ panel.border              : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ panel.spacing             : 'simpleUnit' num 5.5points
  ..- attr(*, "unit")= int 8
 $ panel.spacing.x           : NULL
 $ panel.spacing.y           : NULL
 $ panel.grid                :List of 6
  ..$ colour       : chr "grey92"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ lineend      : NULL
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ panel.grid.major          : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ panel.grid.minor          : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ panel.grid.major.x        : NULL
 $ panel.grid.major.y        : NULL
 $ panel.grid.minor.x        : NULL
 $ panel.grid.minor.y        : NULL
 $ panel.ontop               : logi FALSE
 $ plot.background           :List of 5
  ..$ fill         : NULL
  ..$ colour       : chr "white"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ plot.title                :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 1.2
  ..$ hjust        : num 0
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 5.5points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.title.position       : chr "panel"
 $ plot.subtitle             :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 5.5points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.caption              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : num 1
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 5.5points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.caption.position     : chr "panel"
 $ plot.tag                  :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 1.2
  ..$ hjust        : num 0.5
  ..$ vjust        : num 0.5
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.tag.position         : chr "topleft"
 $ plot.margin               : 'margin' num [1:4] 5.5points 5.5points 5.5points 5.5points
  ..- attr(*, "unit")= int 8
 $ strip.background          :List of 5
  ..$ fill         : chr "white"
  ..$ colour       : chr "black"
  ..$ linewidth    : 'rel' num 2
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ strip.background.x        : NULL
 $ strip.background.y        : NULL
 $ strip.clip                : chr "inherit"
 $ strip.placement           : chr "inside"
 $ strip.text                :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : chr "grey10"
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 4.4points 4.4points 4.4points 4.4points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ strip.text.x              : NULL
 $ strip.text.x.bottom       : NULL
 $ strip.text.x.top          : NULL
 $ strip.text.y              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : num -90
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ strip.text.y.left         :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : num 90
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ strip.text.y.right        : NULL
 $ strip.switch.pad.grid     : 'simpleUnit' num 2.75points
  ..- attr(*, "unit")= int 8
 $ strip.switch.pad.wrap     : 'simpleUnit' num 2.75points
  ..- attr(*, "unit")= int 8
 - attr(*, "class")= chr [1:2] "theme" "gg"
 - attr(*, "complete")= logi TRUE
 - attr(*, "validate")= logi TRUE

$coordinates
<ggproto object: Class CoordCartesian, Coord, gg>
    aspect: function
    backtransform_range: function
    clip: on
    default: TRUE
    distance: function
    expand: TRUE
    is_free: function
    is_linear: function
    labels: function
    limits: list
    modify_scales: function
    range: function
    render_axis_h: function
    render_axis_v: function
    render_bg: function
    render_fg: function
    setup_data: function
    setup_layout: function
    setup_panel_guides: function
    setup_panel_params: function
    setup_params: function
    train_panel_guides: function
    transform: function
    super:  <ggproto object: Class CoordCartesian, Coord, gg>
p2

any(is.na(p2))
[1] FALSE
head(p2)
$data
# A tsibble: 145 x 3 [1]
# Key:       meal_id [1]
   meal_id  week sum_orders
     <dbl> <dbl>      <dbl>
 1    1062     1       4958
 2    1062     2       3793
 3    1062     3       4550
 4    1062     4       4715
 5    1062     5       4120
 6    1062     6       5318
 7    1062     7       5658
 8    1062     8       5081
 9    1062     9       6647
10    1062    10       6242
# ℹ 135 more rows

$layers
$layers[[1]]
geom_line: na.rm = FALSE, orientation = NA
stat_identity: na.rm = FALSE
position_identity 

$layers[[2]]
mapping: x = ~week, y = ~sum_orders 
geom_line: na.rm = FALSE, orientation = NA
stat_identity: na.rm = FALSE
position_identity 


$scales
<ggproto object: Class ScalesList, gg>
    add: function
    clone: function
    find: function
    get_scales: function
    has_scale: function
    input: function
    n: function
    non_position_scales: function
    scales: list
    super:  <ggproto object: Class ScalesList, gg>

$mapping
Aesthetic mapping: 
* `x` -> `week`
* `y` -> `sum_orders`

$theme
List of 97
 $ line                      :List of 6
  ..$ colour       : chr "black"
  ..$ linewidth    : num 0.5
  ..$ linetype     : num 1
  ..$ lineend      : chr "butt"
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ rect                      :List of 5
  ..$ fill         : chr "white"
  ..$ colour       : chr "black"
  ..$ linewidth    : num 0.5
  ..$ linetype     : num 1
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ text                      :List of 11
  ..$ family       : chr ""
  ..$ face         : chr "plain"
  ..$ colour       : chr "black"
  ..$ size         : num 11
  ..$ hjust        : num 0.5
  ..$ vjust        : num 0.5
  ..$ angle        : num 0
  ..$ lineheight   : num 0.9
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ title                     : NULL
 $ aspect.ratio              : NULL
 $ axis.title                : NULL
 $ axis.title.x              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 2.75points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.x.top          :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 2.75points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.x.bottom       : NULL
 $ axis.title.y              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : num 90
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 2.75points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.y.left         : NULL
 $ axis.title.y.right        :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : num -90
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.75points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text                 :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : chr "grey30"
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x               :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 2.2points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x.top           :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 2.2points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x.bottom        : NULL
 $ axis.text.y               :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 1
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 2.2points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.y.left          : NULL
 $ axis.text.y.right         :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.2points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.ticks                :List of 6
  ..$ colour       : chr "grey20"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ lineend      : NULL
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ axis.ticks.x              : NULL
 $ axis.ticks.x.top          : NULL
 $ axis.ticks.x.bottom       : NULL
 $ axis.ticks.y              : NULL
 $ axis.ticks.y.left         : NULL
 $ axis.ticks.y.right        : NULL
 $ axis.ticks.length         : 'simpleUnit' num 2.75points
  ..- attr(*, "unit")= int 8
 $ axis.ticks.length.x       : NULL
 $ axis.ticks.length.x.top   : NULL
 $ axis.ticks.length.x.bottom: NULL
 $ axis.ticks.length.y       : NULL
 $ axis.ticks.length.y.left  : NULL
 $ axis.ticks.length.y.right : NULL
 $ axis.line                 :List of 6
  ..$ colour       : chr "black"
  ..$ linewidth    : 'rel' num 1
  ..$ linetype     : NULL
  ..$ lineend      : NULL
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ axis.line.x               : NULL
 $ axis.line.x.top           : NULL
 $ axis.line.x.bottom        : NULL
 $ axis.line.y               : NULL
 $ axis.line.y.left          : NULL
 $ axis.line.y.right         : NULL
 $ legend.background         :List of 5
  ..$ fill         : NULL
  ..$ colour       : logi NA
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ legend.margin             : 'margin' num [1:4] 5.5points 5.5points 5.5points 5.5points
  ..- attr(*, "unit")= int 8
 $ legend.spacing            : 'simpleUnit' num 11points
  ..- attr(*, "unit")= int 8
 $ legend.spacing.x          : NULL
 $ legend.spacing.y          : NULL
 $ legend.key                : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ legend.key.size           : 'simpleUnit' num 1.2lines
  ..- attr(*, "unit")= int 3
 $ legend.key.height         : NULL
 $ legend.key.width          : NULL
 $ legend.text               :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ legend.text.align         : NULL
 $ legend.title              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ legend.title.align        : NULL
 $ legend.position           : chr "right"
 $ legend.direction          : NULL
 $ legend.justification      : chr "center"
 $ legend.box                : NULL
 $ legend.box.just           : NULL
 $ legend.box.margin         : 'margin' num [1:4] 0cm 0cm 0cm 0cm
  ..- attr(*, "unit")= int 1
 $ legend.box.background     : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ legend.box.spacing        : 'simpleUnit' num 11points
  ..- attr(*, "unit")= int 8
 $ panel.background          :List of 5
  ..$ fill         : chr "white"
  ..$ colour       : logi NA
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ panel.border              : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ panel.spacing             : 'simpleUnit' num 5.5points
  ..- attr(*, "unit")= int 8
 $ panel.spacing.x           : NULL
 $ panel.spacing.y           : NULL
 $ panel.grid                :List of 6
  ..$ colour       : chr "grey92"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ lineend      : NULL
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ panel.grid.major          : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ panel.grid.minor          : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ panel.grid.major.x        : NULL
 $ panel.grid.major.y        : NULL
 $ panel.grid.minor.x        : NULL
 $ panel.grid.minor.y        : NULL
 $ panel.ontop               : logi FALSE
 $ plot.background           :List of 5
  ..$ fill         : NULL
  ..$ colour       : chr "white"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ plot.title                :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 1.2
  ..$ hjust        : num 0
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 5.5points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.title.position       : chr "panel"
 $ plot.subtitle             :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 5.5points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.caption              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : num 1
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 5.5points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.caption.position     : chr "panel"
 $ plot.tag                  :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 1.2
  ..$ hjust        : num 0.5
  ..$ vjust        : num 0.5
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.tag.position         : chr "topleft"
 $ plot.margin               : 'margin' num [1:4] 5.5points 5.5points 5.5points 5.5points
  ..- attr(*, "unit")= int 8
 $ strip.background          :List of 5
  ..$ fill         : chr "white"
  ..$ colour       : chr "black"
  ..$ linewidth    : 'rel' num 2
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ strip.background.x        : NULL
 $ strip.background.y        : NULL
 $ strip.clip                : chr "inherit"
 $ strip.placement           : chr "inside"
 $ strip.text                :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : chr "grey10"
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 4.4points 4.4points 4.4points 4.4points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ strip.text.x              : NULL
 $ strip.text.x.bottom       : NULL
 $ strip.text.x.top          : NULL
 $ strip.text.y              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : num -90
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ strip.text.y.left         :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : num 90
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ strip.text.y.right        : NULL
 $ strip.switch.pad.grid     : 'simpleUnit' num 2.75points
  ..- attr(*, "unit")= int 8
 $ strip.switch.pad.wrap     : 'simpleUnit' num 2.75points
  ..- attr(*, "unit")= int 8
 - attr(*, "class")= chr [1:2] "theme" "gg"
 - attr(*, "complete")= logi TRUE
 - attr(*, "validate")= logi TRUE

$coordinates
<ggproto object: Class CoordCartesian, Coord, gg>
    aspect: function
    backtransform_range: function
    clip: on
    default: TRUE
    distance: function
    expand: TRUE
    is_free: function
    is_linear: function
    labels: function
    limits: list
    modify_scales: function
    range: function
    render_axis_h: function
    render_axis_v: function
    render_bg: function
    render_fg: function
    setup_data: function
    setup_layout: function
    setup_panel_guides: function
    setup_panel_params: function
    setup_params: function
    train_panel_guides: function
    transform: function
    super:  <ggproto object: Class CoordCartesian, Coord, gg>
p3

any(is.na(p3))
[1] FALSE
head(p3)
$data
# A tsibble: 145 x 3 [1]
# Key:       meal_id [1]
   meal_id  week sum_orders
     <dbl> <dbl>      <dbl>
 1    1062     1      14128
 2    1062     2      12359
 3    1062     3      12941
 4    1062     4      15391
 5    1062     5      12175
 6    1062     6      16635
 7    1062     7      18638
 8    1062     8      15750
 9    1062     9      19184
10    1062    10      18806
# ℹ 135 more rows

$layers
$layers[[1]]
geom_line: na.rm = FALSE, orientation = NA
stat_identity: na.rm = FALSE
position_identity 

$layers[[2]]
mapping: x = ~week, y = ~sum_orders 
geom_line: na.rm = FALSE, orientation = NA
stat_identity: na.rm = FALSE
position_identity 


$scales
<ggproto object: Class ScalesList, gg>
    add: function
    clone: function
    find: function
    get_scales: function
    has_scale: function
    input: function
    n: function
    non_position_scales: function
    scales: list
    super:  <ggproto object: Class ScalesList, gg>

$mapping
Aesthetic mapping: 
* `x` -> `week`
* `y` -> `sum_orders`

$theme
List of 97
 $ line                      :List of 6
  ..$ colour       : chr "black"
  ..$ linewidth    : num 0.5
  ..$ linetype     : num 1
  ..$ lineend      : chr "butt"
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ rect                      :List of 5
  ..$ fill         : chr "white"
  ..$ colour       : chr "black"
  ..$ linewidth    : num 0.5
  ..$ linetype     : num 1
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ text                      :List of 11
  ..$ family       : chr ""
  ..$ face         : chr "plain"
  ..$ colour       : chr "black"
  ..$ size         : num 11
  ..$ hjust        : num 0.5
  ..$ vjust        : num 0.5
  ..$ angle        : num 0
  ..$ lineheight   : num 0.9
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ title                     : NULL
 $ aspect.ratio              : NULL
 $ axis.title                : NULL
 $ axis.title.x              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 2.75points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.x.top          :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 2.75points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.x.bottom       : NULL
 $ axis.title.y              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : num 90
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 2.75points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.y.left         : NULL
 $ axis.title.y.right        :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : num -90
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.75points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text                 :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : chr "grey30"
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x               :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 2.2points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x.top           :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 2.2points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x.bottom        : NULL
 $ axis.text.y               :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 1
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 2.2points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.y.left          : NULL
 $ axis.text.y.right         :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.2points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.ticks                :List of 6
  ..$ colour       : chr "grey20"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ lineend      : NULL
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ axis.ticks.x              : NULL
 $ axis.ticks.x.top          : NULL
 $ axis.ticks.x.bottom       : NULL
 $ axis.ticks.y              : NULL
 $ axis.ticks.y.left         : NULL
 $ axis.ticks.y.right        : NULL
 $ axis.ticks.length         : 'simpleUnit' num 2.75points
  ..- attr(*, "unit")= int 8
 $ axis.ticks.length.x       : NULL
 $ axis.ticks.length.x.top   : NULL
 $ axis.ticks.length.x.bottom: NULL
 $ axis.ticks.length.y       : NULL
 $ axis.ticks.length.y.left  : NULL
 $ axis.ticks.length.y.right : NULL
 $ axis.line                 :List of 6
  ..$ colour       : chr "black"
  ..$ linewidth    : 'rel' num 1
  ..$ linetype     : NULL
  ..$ lineend      : NULL
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ axis.line.x               : NULL
 $ axis.line.x.top           : NULL
 $ axis.line.x.bottom        : NULL
 $ axis.line.y               : NULL
 $ axis.line.y.left          : NULL
 $ axis.line.y.right         : NULL
 $ legend.background         :List of 5
  ..$ fill         : NULL
  ..$ colour       : logi NA
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ legend.margin             : 'margin' num [1:4] 5.5points 5.5points 5.5points 5.5points
  ..- attr(*, "unit")= int 8
 $ legend.spacing            : 'simpleUnit' num 11points
  ..- attr(*, "unit")= int 8
 $ legend.spacing.x          : NULL
 $ legend.spacing.y          : NULL
 $ legend.key                : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ legend.key.size           : 'simpleUnit' num 1.2lines
  ..- attr(*, "unit")= int 3
 $ legend.key.height         : NULL
 $ legend.key.width          : NULL
 $ legend.text               :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ legend.text.align         : NULL
 $ legend.title              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ legend.title.align        : NULL
 $ legend.position           : chr "right"
 $ legend.direction          : NULL
 $ legend.justification      : chr "center"
 $ legend.box                : NULL
 $ legend.box.just           : NULL
 $ legend.box.margin         : 'margin' num [1:4] 0cm 0cm 0cm 0cm
  ..- attr(*, "unit")= int 1
 $ legend.box.background     : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ legend.box.spacing        : 'simpleUnit' num 11points
  ..- attr(*, "unit")= int 8
 $ panel.background          :List of 5
  ..$ fill         : chr "white"
  ..$ colour       : logi NA
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ panel.border              : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ panel.spacing             : 'simpleUnit' num 5.5points
  ..- attr(*, "unit")= int 8
 $ panel.spacing.x           : NULL
 $ panel.spacing.y           : NULL
 $ panel.grid                :List of 6
  ..$ colour       : chr "grey92"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ lineend      : NULL
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ panel.grid.major          : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ panel.grid.minor          : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ panel.grid.major.x        : NULL
 $ panel.grid.major.y        : NULL
 $ panel.grid.minor.x        : NULL
 $ panel.grid.minor.y        : NULL
 $ panel.ontop               : logi FALSE
 $ plot.background           :List of 5
  ..$ fill         : NULL
  ..$ colour       : chr "white"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ plot.title                :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 1.2
  ..$ hjust        : num 0
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 5.5points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.title.position       : chr "panel"
 $ plot.subtitle             :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 5.5points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.caption              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : num 1
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 5.5points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.caption.position     : chr "panel"
 $ plot.tag                  :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 1.2
  ..$ hjust        : num 0.5
  ..$ vjust        : num 0.5
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.tag.position         : chr "topleft"
 $ plot.margin               : 'margin' num [1:4] 5.5points 5.5points 5.5points 5.5points
  ..- attr(*, "unit")= int 8
 $ strip.background          :List of 5
  ..$ fill         : chr "white"
  ..$ colour       : chr "black"
  ..$ linewidth    : 'rel' num 2
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ strip.background.x        : NULL
 $ strip.background.y        : NULL
 $ strip.clip                : chr "inherit"
 $ strip.placement           : chr "inside"
 $ strip.text                :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : chr "grey10"
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 4.4points 4.4points 4.4points 4.4points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ strip.text.x              : NULL
 $ strip.text.x.bottom       : NULL
 $ strip.text.x.top          : NULL
 $ strip.text.y              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : num -90
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ strip.text.y.left         :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : num 90
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ strip.text.y.right        : NULL
 $ strip.switch.pad.grid     : 'simpleUnit' num 2.75points
  ..- attr(*, "unit")= int 8
 $ strip.switch.pad.wrap     : 'simpleUnit' num 2.75points
  ..- attr(*, "unit")= int 8
 - attr(*, "class")= chr [1:2] "theme" "gg"
 - attr(*, "complete")= logi TRUE
 - attr(*, "validate")= logi TRUE

$coordinates
<ggproto object: Class CoordCartesian, Coord, gg>
    aspect: function
    backtransform_range: function
    clip: on
    default: TRUE
    distance: function
    expand: TRUE
    is_free: function
    is_linear: function
    labels: function
    limits: list
    modify_scales: function
    range: function
    render_axis_h: function
    render_axis_v: function
    render_bg: function
    render_fg: function
    setup_data: function
    setup_layout: function
    setup_panel_guides: function
    setup_panel_params: function
    setup_params: function
    train_panel_guides: function
    transform: function
    super:  <ggproto object: Class CoordCartesian, Coord, gg>
p1/p2/p3

Aggregated forecast plot
agg <- ts %>% 
  aggregate_key(cuisine*category*meal_id*(region_code/city_code/center_id), sum_orders=sum(num_orders)) %>% 
  index_by(week)

agg_fc <- fc %>% 
  as_tsibble(index=week, key=cm_id) %>% 
  select(-c(2,4)) %>% 
  rename(num_orders=.mean) %>% 
  aggregate_key(cuisine*category*meal_id*(region_code/city_code/center_id), sum_orders=sum(num_orders))

all_agg <- agg %>% 
  filter(is_aggregated(meal_id), is_aggregated(cuisine), is_aggregated(category),
         is_aggregated(region_code))

all_fc_agg <- agg_fc %>% 
  filter(is_aggregated(meal_id), is_aggregated(cuisine), is_aggregated(category),
         is_aggregated(region_code))

p1 <- all_agg %>% 
  ggplot(aes(week, sum_orders))+
  geom_line()+
  geom_line(data=all_fc_agg, aes(week, sum_orders), size=1, col="blue")+
  labs(title = "All aggregated orders")+
  theme_bw()+
  theme(plot.title = element_text(size = 16))
cuisine_agg <- agg %>% 
  filter(is_aggregated(meal_id), !is_aggregated(cuisine), is_aggregated(category),
         is_aggregated(region_code))
cuisine_fc_agg <- agg_fc %>% 
  filter(is_aggregated(meal_id), !is_aggregated(cuisine), is_aggregated(category),
         is_aggregated(region_code))
cuisine_agg$cuisine <- format(cuisine_agg$cuisine)
cuisine_fc_agg$cuisine <- format(cuisine_fc_agg$cuisine)

p2 <- cuisine_agg %>% 
  ggplot(aes(week, sum_orders))+
  geom_line(aes(group=cuisine, col=cuisine), show.legend = TRUE)+
  geom_line(data=cuisine_fc_agg, aes(week, sum_orders, group=cuisine), size=1, col="blue", show.legend = TRUE)+
  facet_wrap(~cuisine, scales = "free_y")+
  labs(title = "Orders by cuisine")+
  coord_cartesian(xlim = c(100, 155))+
  theme_bw()+
  theme(plot.title = element_text(size = 16))
category_agg <- agg %>% 
  filter(is_aggregated(meal_id), is_aggregated(cuisine), !is_aggregated(category),
         is_aggregated(region_code))
category_fc_agg <- agg_fc %>% 
  filter(is_aggregated(meal_id), is_aggregated(cuisine), !is_aggregated(category),
         is_aggregated(region_code))
category_agg$category <- format(category_agg$category)
category_fc_agg$category <- format(category_fc_agg$category)

p3 <- category_agg %>% 
  ggplot(aes(week, sum_orders))+
  geom_line(aes(group=category, col=category), show.legend = FALSE)+
  geom_line(data=category_fc_agg, aes(week, sum_orders, group=category), size=1, col="blue", show.legend = FALSE)+
  facet_wrap(~category, scales = "free_y")+
  labs(title = "Orders by category")+
  coord_cartesian(xlim = c(100, 155))+
  theme_bw()
  theme(plot.title = element_text(size = 16))
List of 1
 $ plot.title:List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : num 16
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi FALSE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 - attr(*, "class")= chr [1:2] "theme" "gg"
 - attr(*, "complete")= logi FALSE
 - attr(*, "validate")= logi TRUE